package org.fujene.structure;

import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * It contains terms like {@link java.util.ArrayList}, with a function to count
 * term frequencies.
 * 
 * @author Yusuke Fujisaka
 * 
 */
public class TermList implements Iterable<Term>, Collection<Term> {
	private Term[] terms;
	private int currentLength;
	private int called;

	public TermList() {
		this(10);
	}

	public TermList(int initial) {
		terms = new Term[initial];
		currentLength = 0;
	}

	@Override
	public boolean add(Term term) {
		int i;
		boolean found = false;

		for (i = 0; i < terms.length && terms[i] != null; i++)
			if (terms[i].equals(term)) {
				found = true;
				synchronized(terms){
					terms[i].increment();
				}
			}

		if (!found) {
			synchronized(terms){
				if (i >= terms.length)
					// 拡張
					terms = Arrays.copyOf(terms, (int) (1.5 * currentLength));
				terms[i] = term;
			}
			currentLength++;
		}
		return true;
	}

	public int size() {
		return currentLength;
	}

	public Term get(int index) {
		if (index >= currentLength)
			return null;

		return terms[index];
	}

	@Override
	public Iterator<Term> iterator() {
		called = 0;
		return new Iterator<Term>() {
			@Override
			public boolean hasNext() {
				return called < currentLength;
			}

			@Override
			public Term next() {
				if (called < currentLength)
					return terms[called++];
				else
					throw new NoSuchElementException();
			}

			@Override
			public void remove() {
				throw new UnsupportedOperationException();
			}
		};
	}

	@Override
	public boolean isEmpty() {
		return currentLength == 0;
	}

	@Override
	public boolean contains(Object o) {
		for (int i = 0; i < terms.length; i++) {
			if(terms[i].equals(o))
				return true;
		}
		return false;
	}

	@Override
	public Object[] toArray() {
		return Arrays.copyOf(terms, terms.length);
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T[] toArray(T[] a) {
		if (a instanceof Term[])
			return (T[]) Arrays.copyOf(terms, terms.length);

		return null;
	}

	@Override
	public boolean remove(Object o) {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean containsAll(Collection<?> c) {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean addAll(Collection<? extends Term> c) {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean removeAll(Collection<?> c) {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean retainAll(Collection<?> c) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void clear() {
		// いったん消して復活
		terms = null;
		
		terms = new Term[10];
		currentLength = 0;
		
	}
}
